<?php
namespace app\common\lib\line;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7;
class SinaKline implements kline
{
    public static $sina_current_url = "https://hq.sinajs.cn/?rn=%slist=%s";   //新浪当前行情
    public static $sina_min_kline_url = "https://vip.stock.finance.sina.com.cn/forex/api/jsonp.php/var%20[symbol]_[min]_[microtime]=/NewForexService.getMinKline?symbol=[symbol]&scale=[min]&datalen=[len]";//K分线
    public static $sina_day_kline_url = "https://vip.stock.finance.sina.com.cn/forex/api/jsonp.php/var%20[symbol][day]=/NewForexService.getDayKLine?symbol=[symbol]&_=[day]";//K日线
    public static $headers = [
        "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
        'Accept-Language' => 'zh-CN,zh;q=0.9',
        'Accept-Charset' => 'utf-8',
    ];
    public static $options =[
        'verify' => false,
        'allow_redirects' => false
    ];
    public static $_instance = null;
    public static $client =null;
    public  static function getInstance() {
        if (empty(self::$_instance)) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
    private function __construct()
    {
        self::$client = new Client();
    }
    public function setHeaders($key,$val)
    {
        self::$headers[$key] = $val;
        $this->setOptions("headers",self::$headers);
        return $this;
    }
    public   function setOptions($key,$val) {
        self::$options[$key] = $val;
    }
    //通过新浪获取k线图
    public  function getList($symbols="")
    {
        $milliseconds = strval(round(microtime(true) * 1000));
        $url = sprintf(self::$sina_current_url,$milliseconds ,$symbols);
        $this->setHeaders("Referer","https://finance.sina.com.cn")
            ->setHeaders("Host","hq.sinajs.cn");
        try {
            $response = self::$client->get($url,self::$options);
            $type = $response->getHeader('content-type');
            $parsed = Psr7\parse_header($type);
            $body = (string)$response->getBody();
            if (empty($body)) {
                return false;
            }
            $utf8Body = mb_convert_encoding($body, 'UTF-8', $parsed[0]['charset'] ?: 'UTF-8');
            $data = explode(';',$utf8Body);
            if (empty($data)) {
                return false;
            }
            array_pop($data);
            $list =[];
            foreach($data as $key=>$v) {
                $res = explode("=", $v);
                if (empty($res)||empty($res[1])) {
                    continue;
                }
                $res = explode(",", $res[1]);
                if (empty($res)||empty($res[1])) {
                    break;
                }
                $tmp["name"] = trim($res[9]); //名称
                $tmp["price"] = $res[8]; //当前价格
                $tmp["close"] = $res[3]; //昨日收盘
                $tmp["open"] = $res[5];//开盘价
                $tmp["higher"] = $res[6];//最高
                $tmp["lower"] = $res[7];//最低
                $tmp["updownCount"] = $res[8] - $res[3];//涨跌
                $tmp["bofu"] = $res[6] - $res[7];//波幅
                $tmp["date"] = $res[10] . " " . $res[0];//当前时间
                $tmp["percent"] = (10000 * ($res[8] - $res[3]) / $res[3]) / 100 + "%"; //涨跌
                $tmp["updown"] = $res[8] > $res[3] ? "up" : "down";//涨还是跌
                $tmp["zf"] = (10000 * ($res[6] - $res[7]) / $res[3]) / 100 + "%"; //振幅
                $list[$key] = $tmp;
            }
        } catch (\Exception $e) {
            trace($e->getMessage(),'error');
            throw new \think\Exception($e, 100006);
        }
        return $list;
    }
    //
    public function getMinLine($min,$len,$symbol)
    {
        $milliseconds = strval(round(microtime(true) * 1000));;
        $url =str_replace(["[symbol]","[min]","[microtime]","[len]"],[$symbol,$min,$milliseconds,$len],self::$sina_min_kline_url);
        $this->setHeaders("host","vip.stock.finance.sina.com.cn")
            ->setHeaders("Referer","https://finance.sina.com.cn");
        $data = "";
        try {
            $response = self::$client->get($url,self::$options);
            $body = (string)$response->getBody();
            if (empty($body)) {
                return;
            }
            $res =explode('(',$body);
            if (empty($res)||empty($res[1])) {
                return;
            }
            $data = str_replace(");","",$res[1]);
        } catch (\Exception $e) {
            trace($e->getMessage(),'error');
            throw new \think\Exception($e, 100006);
        }
        return $data;
    }

    public function getDayLine($symbol)
    {
        $day = date("Y_m_d");
        $this->setHeaders("host","vip.stock.finance.sina.com.cn")
            ->setHeaders("Referer","https://finance.sina.com.cn");
        $url =str_replace(["[symbol]","[day]"],[$symbol,$day],self::$sina_day_kline_url);
        try {
            $response = self::$client->get($url,self::$options);
            $body = (string)$response->getBody();
            $content = trim($body,'"');
            if (empty($content)) {
                return;
            }
            $res =explode('(',$content);
            if (empty($res)||empty($res[1])) {
                return;
            }
            $str= str_replace(");","",$res[1]);
            $data = explode("|",$str);
        } catch (\Exception $e) {
            trace($e->getMessage(),'error');
            throw new \think\Exception($e, 100006);
        }
        return $data;
    }
}